var app = {
  version: "0.1.0",

  data: {
    /**
     * 回调缓存
     */
    callbackHandlers: {},
  },

  /**
   * 生成uuid
   *
   * @returns String uuid
   */
  uuid: function () {
    var d = Date.now();
    if (
      typeof performance !== "undefined" &&
      typeof performance.now === "function"
    ) {
      d += performance.now(); //use high-precision timer if available
    }
    return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
      /[xy]/g,
      function (c) {
        var r = (d + Math.random() * 16) % 16 | 0;
        d = Math.floor(d / 16);
        return (c === "x" ? r : (r & 0x3) | 0x8).toString(16);
      }
    );
  },

  /**
   * 判断客户端平台。
   * 包括iOS、Android、PC。
   */
  clientType: (() => {
    let client = "";
    if (/(iPhone|iPad|iPod|iOS|Mac OS)/i.test(navigator.userAgent)) {
      //判断iPhone|iPad|iPod|iOS
      client = "iOS";
    } else if (/(Android)/i.test(navigator.userAgent)) {
      //判断Android
      client = "Android";
    } else {
      client = "PC";
    }
    return client;
  })(),

  callIosMessageHandler: function (handler, param) {
    let messageHandler =
      window.webkit && window.webkit.messageHandlers
        ? window.webkit.messageHandlers[handler]
        : undefined;

    return messageHandler ? messageHandler.postMessage(param) : undefined;
  },

  callAndroidMessageHandler: function (handler, param) {
    return window.messageHandlers && window.messageHandlers[handler]
      ? param
        ? window.messageHandlers[handler](param)
        : window.messageHandlers[handler]()
      : undefined;
  },

  /**
   * 调用客户端提供的方法，不同平台使用不同的方法。
   *
   * @param {String} messageId 方法（消息）id。
   * @param {Object} params 参数。
   */
  postMessage: function (messageId, params) {
    let message = {
      id: messageId,
      params: params,
    };

    switch (this.clientType) {
      case "iOS":
        this.callIosMessageHandler("app", message);
        break;

      case "Android":
        this.callAndroidMessageHandler("onMessage", JSON.stringify(message));
        break;

      default:
        console("Other client type, not post message!");
        break;
    }
  },

  /**
   * 通用成功回调
   *
   * @param {String} uuid
   * @param {Int} code
   * @param {String} message
   */
  callbackSuccess: function (uuid, code, message, data) {
    if (this.data.callbackHandlers[uuid] == null) {
      return;
    }
    if (this.data.callbackHandlers[uuid].success != null) {
      this.data.callbackHandlers[uuid].success({ code, message, data });
    }
  },

  /**
   * 通用失败回调
   *
   * @param {Sting} uuid
   * @param {Int} code
   * @param {String} message
   */
  callbackFail: function (uuid, code, message, data) {
    if (this.data.callbackHandlers[uuid] == null) {
      return;
    }
    if (this.data.callbackHandlers[uuid].fail != null) {
      this.data.callbackHandlers[uuid].fail({ code, message, data });
    }
  },

  /**
   * 通用完成回调
   *
   * @param {String} uuid
   * @param {Int} code
   * @param {String} message
   */
  callbackComplete: function (uuid) {
    if (this.data.callbackHandlers[uuid] == null) {
      return;
    }
    if (this.data.callbackHandlers[uuid].complete != null) {
      this.data.callbackHandlers[uuid].complete();
    }
    delete this.data.callbackHandlers[uuid];
  },

  /**
   * 生成原生交互参数
   *
   * @param {*} object
   * @returns
   */
  createParams: function (object) {
    let uuid = this.uuid();
    this.data.callbackHandlers[uuid] = object;

    let params = {
      uuid: uuid,
      ...object,
    };
    params["success"] = "app.callbackSuccess";
    params["fail"] = "app.callbackFail";
    params["complete"] = "app.callbackComplete";

    return params;
  },

  /**
   * app version
   */
  get appVersion() {
    switch (this.clientType) {
      case "iOS":
        return window.appVersion;

      case "Android":
        return this.callAndroidMessageHandler("getAppVersion");

      default:
        return null;
    }
  },

  /**
   * 主题
   */
  theme: {
    /**
     * 主题色
     */
    get primaryColor() {
      return app.clientType == "iOS"
        ? window.primaryColor
        : this.callAndroidMessageHandler("getPrimaryColor");
    },
  },

  /**
   * 状态栏高度
   */
  get statusBarHeight() {
    switch (this.clientType) {
      case "iOS":
        return window.statusBarHeight;

      case "Android":
        return this.callAndroidMessageHandler("getStatusBarHeight");

      default:
        return null;
    }
  },

  /**
   * 发起 HTTP 网络请求
   *
   * @param {*} object
   */
  request: function (object) {
    this.postMessage("request", this.createParams(object));
  },

  /**
   * 关闭弹窗
   *
   * @param {*} object
   */
  closeDialog: function (object) {
    this.postMessage("closeDialog", this.createParams(object));
  },

  /**
   * 提示弹窗,只有确认按钮
   * @param object
   */
  alert: function (object) {
    this.postMessage("alert", this.createParams(object));
  },

  /**
   * 提示弹窗,确认和取消
   * @param object
   */
  confirm: function (object) {
    this.postMessage("confirm", this.createParams(object));
  },

  /**
   * 带输入框的弹窗
   * @param object
   */
  prompt: function (object) {
    this.postMessage("prompt", this.createParams(object));
  },

  /**
   * 设置导航栏右侧按钮
   * @param object
   */
  setRightMenus: function (object) {
    this.createOnTapCallback(object["data"]);

    this.postMessage("setRightMenus", this.createParams(object));
  },

  createOnTapCallback: function (menuDatas) {
    menuDatas.forEach((menuData) => {
      if (menuData["onTap"]) {
        let uuid = this.uuid();
        this.data.callbackHandlers[uuid] = {
          menuData: menuData,
          onTap: menuData["onTap"],
        };

        menuData["onTap"] = `app.callbackOnTap("${uuid}")`;
      }

      if (menuData["children"]) {
        this.createOnTapCallback(menuData["children"]);
      }
    });
  },

  callbackOnTap: function (uuid) {
    const onTapHandler = this.data.callbackHandlers[uuid];
    if (onTapHandler == null) {
      return;
    }

    onTapHandler.onTap(onTapHandler.menuData);
  },

  /**
   * 调用App原生提供的分享功能
   * @param object
   */
  share: function (object) {
    this.postMessage("share", this.createParams(object));
  },

   /**
   * 前端添加追踪之后通知原生刷新页面
   * @param object
   */
  postWebViewMessage: function (object) {
    this.postMessage("postWebViewMessage", this.createParams(object));
  },
};
